﻿//
//  Manyou.Toolkit.ManyouSession.cs:
//  Authors:
//	Bryan Chow (cabir.zhou@gmail.com)
//
//
//  No Trademark License- This license does not grant you rights to use any 
//  contributors' name, logo, or trademarks.
//
//  If you bring a patent claim against any contributor over patents that you
//  claim are infringed by the software, your patent license from such 
//  contributor to the software ends automatically.
//
//  If you distribute any portion of the software, you must retain
//  all copyright, patent, trademark, and attribution notices that are present in the software.
//
//  If you distribute any portion of the software in source code form,
//  you may do so only under this license by including a complete copy of this license
//  with your distribution. If you distribute any portion of the software
//  in compiled or object code form, you may only do so under a license that complies with this license.
//
//  The software is licensed "as-is." You bear the risk of using it. 
//  The contributors give no express warranties, guarantees or conditions.
//  You may have additional consumer rights under your local laws which 
//  this license cannot change. To the extent permitted under your local laws,
//  the contributors exclude the implied warranties of merchantability,
//  fitness for a particular purpose and non-infringement.
//

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;

namespace Manyou.Toolkit
{
    public class ManyouSession
    {
        Util util;

        internal Util Util
        {
            get { return util; }
        }

        internal string SessionKey
        {
            get { return GetManyouParam("sessionId"); }
        }

        // use this for plain sessions
        public ManyouSession(string api_key, string shared_secret)
        {
            util = new Util(api_key, shared_secret, "http://api.manyou.com/openapi.php?");
            GetValidParams();
        }


        #region User

        /// <summary>
        /// 根据uid获取用户信息
        /// </summary>
        /// <param name="uid">要获取用户的uid</param>
        /// <returns>用户信息</returns>
        public User GetUserInfo(long uid)
        {
            User[] users = this.GetUserInfo(new long[1] { uid }, User.FIELDS);

            if (users.Length < 1)
                return null;

            return users[0];
        }

        public User[] GetUserInfo(long[] uids, string[] fields)
        {
            List<ManyouParam> param_list = new List<ManyouParam>();

            if (uids == null || uids.Length == 0)
                throw new Exception("uid not provided");

            param_list.Add(ManyouParam.Create("uids", uids));
            param_list.Add(ManyouParam.Create("fields", fields));

            UserInfoResponse rsp = util.GetJsonResponse<UserInfoResponse>("user.getInfo", param_list.ToArray());
            return rsp.Users;
        }

        public Me GetLoggedInUser()
        {
            return new Me(Util.GetIntFromString(((StringResponse)Util.GetJsonResponse<StringResponse>("user.getLoggedInUser")).result), this);
        }

        public bool IsAppAdded()
        {
            return ((BooleanResponse)Util.GetJsonResponse<BooleanResponse>("user.isAppAdded")).result;
        }

        public string GetLoggedInUserLevel()
        {
            return ((StringResponse)Util.GetJsonResponse<StringResponse>("user.getLoggedInUserLevel")).result;
        }

        #endregion

        #region Friend

        public Friend[] GetFriends()
        {
            FriendsResponse response = Util.GetJsonResponse<FriendsResponse>("friend.get");

            Friend[] friends = new Friend[response.UIds.Length];

            for (int i = 0; i < friends.Length; i++)
                friends[i] = new Friend(response.UIds[i], this);

            return friends;
        }

        public bool AreFriends(Friend friend1, Friend friend2)
        {
            return AreFriends(friend1.UId, friend2.UId);
        }

        public bool AreFriends(long uid1, long uid2)
        {
            BooleanResponse response = Util.GetJsonResponse<BooleanResponse>("friend.areFriends",
                   ManyouParam.Create("uid1", uid1),
                   ManyouParam.Create("uid2", uid2));

            return response.result;
        }

        public Friend[] GetAppUsers()
        {
            FriendsResponse response = Util.GetJsonResponse<FriendsResponse>("friend.getAppUsers");

            Friend[] friends = new Friend[response.UIds.Length];

            for (int i = 0; i < friends.Length; i++)
                friends[i] = new Friend(response.UIds[i], this);

            return friends;
        }
        #endregion

        #region feed
        public bool PublishTemplatizedAction(string titleTemplate, string titleData, string bodyTemplate, string bodyData, string bodyGeneral, 
            string image1, string image1Link, string image2, string image2Link, string image3, string image3Link, string image4, string image4Link)//, string targetIds)
        {
            BooleanResponse response = Util.GetJsonResponse<BooleanResponse>("feed.publishTemplatizedAction",
                   ManyouParam.Create("title_template", titleTemplate),
                   ManyouParam.Create("title_data", titleData),
                   ManyouParam.Create("body_template", bodyTemplate),
                   ManyouParam.Create("body_data", bodyData),
                   ManyouParam.Create("body_general", bodyGeneral),
                   ManyouParam.Create("image_1", image1),
                   ManyouParam.Create("image_1_link", image1Link),
                   ManyouParam.Create("image_2", image2),
                   ManyouParam.Create("image_2_link", image2Link),
                   ManyouParam.Create("image_3", image3),
                   ManyouParam.Create("image_3_link", image3Link),
                   ManyouParam.Create("image_4", image4),
                   ManyouParam.Create("image_4_link", image4Link),
                   ManyouParam.Create("target_ids", ""));

            return response.result;
        }
        
        #endregion

        #region Profile
        public bool SetMYML(string myml)
        {
            BooleanResponse response = Util.GetJsonResponse<BooleanResponse>("profile.setMYML",
                   ManyouParam.Create("myml", myml));

            return response.result;
        }

        public string GetMYML()
        {
            StringResponse response = Util.GetJsonResponse<StringResponse>("profile.getMYML");
            return response.result;
        }

        #endregion

        #region Notification
        public Notifications GetNotification()
        {
            NotificationsResponse response = Util.GetJsonResponse<NotificationsResponse>("notification.get");
            return response.result;
        }

        public bool SendNotification(string uids, string msg)
        {
            BooleanResponse response = Util.GetJsonResponse<BooleanResponse>("notification.send",
                   ManyouParam.Create("uids", uids),
                   ManyouParam.Create("msg", msg)
                   );

            return response.result;
        }
        #endregion

        #region Site
        public Site GetSite(int sid)
        { 
            return Util.GetJsonResponse<SingleResponse<Site[]>>("site.get",
                   ManyouParam.Create("sid", sid)
                   ).result[0];
        }
        #endregion


        #region Helper
        public void Redirect(string url)
        {
            if (InMyCanvas())
            {
                HttpContext.Current.Response.Write("<my:redirect url=\"" + url + "\"/>");
            }
            else if (url.IndexOf(GetManyouParam("prefix")) < 0)
            {
                HttpContext.Current.Response.Redirect(url);
            }
            else
            {
                HttpContext.Current.Response.Write("<script type=\"text/javascript\">\ntop.location.href = \"" + url + "\";\n</script>");
            }
        }



        public bool IsValidParams(Dictionary<string, string> parameters, string prefix)
        {
            string sig = parameters["key"];

            parameters.Remove("key");

            if (sig != util.GenerateSig(parameters, prefix))
                return false;
            return true;
        }


        public Dictionary<string, string> GetMyParams(NameValueCollection parameters, string prefix)
        {

            Dictionary<string, string> list = new Dictionary<string, string>();
            if (parameters.Count == 0)
                return list;
            try
            {
                foreach (string key in parameters.AllKeys)
                {
                    if (string.IsNullOrEmpty(key))
                    {
                        continue;
                    }
                    if (key.Length > prefix.Length && key.Substring(0, prefix.Length) == prefix)
                    {
                        list.Add(key.Substring(prefix.Length), parameters[key]);
                    }
                }
            }
            catch
            {
            }

            return list;

        }

        public void GetValidParams()
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            string prefix = "my_sig_";
            parameters = GetMyParams(HttpContext.Current.Request.Form, prefix);


            if (parameters.Count == 0)
            {
                parameters = GetMyParams(HttpContext.Current.Request.QueryString, prefix);
                if (parameters.Count == 0)
                {
                    NameValueCollection nvc = new NameValueCollection();

                    for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++)
                    {
                        nvc.Add(HttpContext.Current.Request.Cookies[i].Name, HttpContext.Current.Request.Cookies[i].Value);
                    }
                    parameters = GetMyParams(nvc, util.ApiKey + "_");
                    string delkeys = string.Empty;
                    foreach (KeyValuePair<string, string> p in parameters)
                    {
                        if (!Util.InArray(p.Key, "uId,sessionId,sId,key"))
                        {
                            delkeys += p.Key + ",";
                            //parameters.Remove(p.Key);
                        }
                    }
                    foreach (string key in delkeys.Split(','))
                    {
                        parameters.Remove(key);
                    }
                        //HttpContext.Current.Response.End();
                    if (IsValidParams(parameters, util.ApiKey + "_"))
                    {
                        util.Parms = parameters;
                    }
                    else
                    {
                        return;
                    }
                }
                else if (IsValidParams(parameters, prefix))
                {
                    try
                    {
                        util.SetCookies(parameters, 3600 * 10);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.ToString());
                    }
                    util.Parms = parameters;
                }

            }
            else if (IsValidParams(parameters, prefix))
            {
                util.Parms = parameters;
            }


        }

        /// <summary>
        /// get current loggedin userid
        /// </summary>
        /// <returns></returns>
        public int GetUid()
        {
            if (util.Parms.ContainsKey("uId"))
            {
                return Util.GetIntFromString(util.Parms["uId"]);
            }

            return Util.GetIntFromString(util.GetCookie(util.ApiKey + "_uId"));
        }

        public bool InMyCanvas()
        {
            return GetManyouParam("in_canvas") == "1";
        }

        public bool InFrame()
        {
            return GetManyouParam("in_iframe") == "1";
        }

        /// <summary>
        /// get current uch site url
        /// </summary>
        /// <returns></returns>
        public string GetManyouParam(string key)
        {
            if (util.Parms.ContainsKey(key))
                return util.Parms[key];
            return util.GetCookie(util.ApiKey + "_" + key);
        }

        public void RequireLogin()
        {
            if (GetUid() <= 0)
            {
                HttpContext.Current.Response.Write("<my:redirect to='require_login' appid=\"" + util.Parms["appId"] + "\"/>");
            }
        }

        /// <summary>
        /// get the login page url
        /// </summary>
        /// <returns></returns>
        public string GetLoginUrl()
        {
            return GetManyouParam("prefix") + "do.php?ac=login&refer=userapp.php?id=" + GetManyouParam("appId");
        }

        /// <summary>
        /// get the app add page url
        /// </summary>
        /// <returns></returns>
        public string GetAddUrl()
        {
            return GetManyouParam("prefix") + "cp.php?ac=userapp&appid=" + GetManyouParam("appId");
        }

        public void RequireAdd()
        {
            if (GetManyouParam("added") != "1")
            {
                HttpContext.Current.Response.Write("<my:redirect to='require_add' appid=\"" + util.Parms["appId"] + "\"/>");
            }
        }

        public string GetUrl(string suffix)
        {
            return string.Format("{0}userapp.php?id={1}&my_suffix={2}", GetManyouParam("prefix"), GetManyouParam("appId"), HttpUtility.UrlEncode(suffix));
        }

        // 返回当前站点Id
        public int GetCurrentSite()
        {
            return Util.GetIntFromString(GetManyouParam("sId"));
        }

        // 返回当前App Id
        public int GetCurrentApp()
        {
            return Util.GetIntFromString(GetManyouParam("appId"));
        }

        // 当前用户是否刚刚安装应用（第一次访问）
        public bool IsInstalled()
        {
            return Util.GetIntFromString(GetManyouParam("installed")) == 1;
        }

        // 当前用户是否刚刚卸载了应用
        public bool IsUninstalled()
        {
            return Util.GetIntFromString(GetManyouParam("uninstalled")) == 1;
        }

        // 站外邀请，获得邀请者在UC Home站点上的uid
        public int GetOutsiteInviter()
        {
            if (Util.GetIntFromString(GetManyouParam("invitedby_ai")) > 0 && IsInstalled())
                return Util.GetIntFromString(GetManyouParam("invitedby_ai"));
            return 0;
        }

        //TODO 站内邀请，获得邀请者在UC Home站点上的uid
        public int GetInsiteInviter()
        {
            return 0;
        }
        #endregion

    }
}

